package com.hundsun.cprs.yyt.service.match.domain;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 一次撮合中,撮合成功的份额数
 * 
 * @author fish
 * 
 */
public class TradeMatchDetail {

    private String id;

    private TradeEntrust entrust;// 订单

    private long matchStockAmount;// 撮合成功委托数,也就是这次撮合,需要从entrust里面扣除多少份额

    private long matchFundAmount;// 撮合成交金额(不包括佣金)

    private long matchCommission;// 本次撮合佣金

    private long matchManagementFund; // 本次匹配的综合管理费

    private TradeMatch match;//

    private long matchPrice;// 成交价格,在连续竞价时,每笔成交都有自己的成交价格

    private Date lastMatchTime;

    private boolean myPriceTrade;// 连续竞价时,是否以我的价格成交
    
    private Integer transactionCount = 0; //一次匹配内买卖双方成组序号

    private Long surplusEntrustAmount = 0L;//当前匹配剩余量

    public TradeMatchDetail() {
        super();
    }

    /**
     * 订单确定份额量成交
     * 
     * @param entrust
     * @param amount
     */
    public TradeMatchDetail(TradeEntrust entrust, long amount) {
        super();
        this.entrust = entrust;
        this.matchStockAmount = amount;
        entrust.setEntrustStatus(this.getEntrustNewStatus());
    }

    /**
     * 订单确定份额量以及价格成交
     * 
     * @param entrust
     * @param amount
     * @param matchPrice
     */
    public TradeMatchDetail(TradeEntrust entrust, long amount, long matchPrice) {
        this(entrust, amount, matchPrice, false);
    }

    public TradeMatchDetail(TradeEntrust entrust, long amount, long matchPrice, boolean isMyPriceTrade) {
        super();
        this.entrust = entrust;
        this.matchStockAmount = amount;
        this.matchPrice = matchPrice;
        this.myPriceTrade = isMyPriceTrade;
        entrust.setEntrustStatus(this.getEntrustNewStatus());
    }
    
    public TradeMatchDetail(TradeEntrust entrust, long amount, long matchPrice, boolean isMyPriceTrade,int transactionCount) {
        super();
        this.entrust = entrust;
        this.matchStockAmount = amount;
        this.matchPrice = matchPrice;
        this.myPriceTrade = isMyPriceTrade;
        this.transactionCount = transactionCount;
        this.surplusEntrustAmount = entrust.getSurplusEntrustAmount();
        entrust.setEntrustStatus(this.getEntrustNewStatus());
    }
    
    /**
     * 撮合后计算 计算佣金 算法:计算本次交易佣金cur=max[(总成交金额+本次成交金额)*佣金比例,最小佣金额] – 已扣除佣金 , 如果cur == 0 不扣，cur > 0 扣除cur的佣金,cur <0 不扣。
     */
    public void calculate() {
        // 本次交易金额
        this.matchFundAmount = this.matchStockAmount * this.getMatchPrice();
        // 到本次交易为止,应该收取佣金
        long commission = this.entrust.getCommissionrate().movePointLeft(3)
            .multiply(new BigDecimal(Math.abs(this.entrust.getBusinessFund()) + this.matchFundAmount)).longValue();
        if (commission < this.entrust.getMinCommission()) {
            commission = this.entrust.getMinCommission();
        }
        long need = commission - this.entrust.getCommissionFund();
        if (need > 0) {
            this.matchCommission = need;
        } else {
            this.matchCommission = 0;
        }
        if (this.entrust.isSell() && matchFundAmount < matchCommission) {
            // 如果卖的时候，佣金比交际金额还高，那就取交易额当佣金，这人卖了份额就只能收入为0,可怜啊
            this.matchCommission = matchFundAmount;
        }
        
        // 到本次交易为止，应该收取的综合管理费
        long managementFund = new BigDecimal(this.entrust.getManagementRate()).movePointLeft(2)
            .multiply(new BigDecimal(Math.abs(this.entrust.getBusinessFund()) + this.matchFundAmount)).longValue();
        long needManagementFund = managementFund - this.entrust.getManagementFund();
        if (needManagementFund > 0) {
            this.matchManagementFund = needManagementFund;
        } else {
            this.matchManagementFund = 0;
        }
        
        this.entrust.addBusinessFund(matchFundAmount);
        this.entrust.addCommissionFund(matchCommission);
        this.entrust.addManagementFund(matchManagementFund);
        this.entrust.calculateGainBusinessFund();
        // 顺便加一下成交笔数
        this.entrust.addTransactions();
        // 再顺便记一下最后成交时间
        this.entrust.setLastMatchTime(this.match.getMatchTime());
        this.entrust.setMatchingSeq(this.match.getMatchSeq());
        // 复制一份entrust对象,进行后续的操作
        this.entrust = this.entrust.clone();
    }

    /**
     * 得到撮合后订单的新状态
     * 
     * @return
     */
    public int getEntrustNewStatus() {
        if (this.entrust.isEntrustAmountAllMatch()) {
            return TradeEntrust.EntrustStatusDealt;
        }
        return TradeEntrust.EntrustStatusPartDealt;
    }

    /**
     * 得到撮合价格,集合竞价返回总的价格,连续竞价每次交易都有一个价格
     * 
     * @return
     */
    public long getMatchPrice() {
        return this.matchPrice;
    }

    /**
     * 得到本交易导致用户账户资金总的出入,如果是买入,则应该是 -(成交额+佣金),如果是卖出,则是 (成交额-佣金)
     * 
     * @return
     */
    public long getTotalFund() {
        if (this.entrust.isBuy()) {
            return -(matchFundAmount + matchCommission);
        } else {
            return matchFundAmount - matchCommission;
        }
    }

    /**
     * 成交价格类型
     * 
     * @return
     */
    public Integer getPriceType() {
        if (this.getMatch().getPriceType() != null) {// 集合竞价
            return this.getMatch().getPriceType();
        }
        // 连续竞价
        if (this.myPriceTrade) {
            // 以我的价格成交
            return this.entrust.isBuy() ? TradeMatch.PriceTypeBuyPrice : TradeMatch.PriceTypeSellPrice;
        } else {
            return this.entrust.isBuy() ? TradeMatch.PriceTypeSellPrice : TradeMatch.PriceTypeBuyPrice;
        }
    }

    /**
     * 得到带正负号的成交份额(买为正,卖为负)
     * 
     * @return
     */
    public long getSignedMatchStockAmount() {
        if (this.entrust.isBuy()) {
            return getMatchStockAmount();
        } else {
            return 0L - getMatchStockAmount();
        }
    }

    /**
     * 得到带正负号的成交金额(买为负,卖为正)
     * 
     * @return
     */
    public long getSignedMatchFundAmount() {
        if (this.entrust.isBuy()) {
            return 0L - this.getMatchFundAmount();
        } else {
            return this.getMatchFundAmount();
        }
    }

    public TradeEntrust getEntrust() {
        return entrust;
    }

    public long getMatchStockAmount() {
        return matchStockAmount;
    }

    public void setMatchStockAmount(long matchStockAmount) {
        this.matchStockAmount = matchStockAmount;
    }

    public long getMatchFundAmount() {
        return matchFundAmount;
    }

    public void setMatchFundAmount(long matchFundAmount) {
        this.matchFundAmount = Math.abs(matchFundAmount);
    }

    public long getMatchCommission() {
        return matchCommission;
    }

    public void setMatchCommission(long matchCommission) {
        this.matchCommission = matchCommission;
    }

    public TradeMatch getMatch() {
        return match;
    }

    public void setMatch(TradeMatch match) {
        this.match = match;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setMatchPrice(long matchPrice) {
        this.matchPrice = matchPrice;
    }

    public Date getLastMatchTime() {
        return lastMatchTime;
    }

    public void setLastMatchTime(Date lastMatchTime) {
        this.lastMatchTime = lastMatchTime;
    }

    public boolean isMyPriceTrade() {
        return myPriceTrade;
    }

    public long getMatchManagementFund() {
        return matchManagementFund;
    }

    public void setMatchManagementFund(long matchManagementFund) {
        this.matchManagementFund = matchManagementFund;
    }

    public int getTransactionCount() {
        return transactionCount;
    }

    public void setTransactionCount(int transactionCount) {
        this.transactionCount = transactionCount;
    }

    public Long getSurplusEntrustAmount() {
        return surplusEntrustAmount;
    }

    public void setSurplusEntrustAmount(Long surplusEntrustAmount) {
        this.surplusEntrustAmount = surplusEntrustAmount;
    }
}
